#include "head.h"

#define VALUE 3

union  semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buff;
};


int create_sem() {
    key_t key = ftok(".", 2021);
    int sem_id;
    if ((sem_id = semget(key, 1, IPC_CREAT | 0666)) < 0) {
        perror("semget");
        return -1;
    }
    return sem_id;
}

int init_sem(int sem_id) {
    union semun arg;
    arg.val = VALUE;
    return semctl(sem_id, 0, SETVAL, arg);
}

int sem_P(int sem_id) {
    struct sembuf sbuff;
    sbuff.sem_num = 0;
    sbuff.sem_op = -1;
    sbuff.sem_flg = SEM_UNDO;
    if (semop(sem_id, &sbuff, 1) == -1) {
        perror("semop");
        return -1;
    }
    return 0;
}

int sem_V(int sem_id) {
    struct sembuf sbuff;
    sbuff.sem_num = 0;
    sbuff.sem_op = 1;
    sbuff.sem_flg = SEM_UNDO;
    if (semop(sem_id, &sbuff, 1) == -1) {
        perror("semop");
        return -1;
    }
    return 0;
}

int sem_Look(int sem_id) {
    int ret;
    if ((ret = semctl(sem_id, 0, GETVAL)) < 0) {
        return -1;
    }
    return ret;
}

int main(int argc, char **argv) {
    int sem_id;
    if ((sem_id = create_sem()) < 0) {
        perror("create_sem");
        exit(1);
    }

    if (argc > 1) {
        if (init_sem(sem_id) < 0) {
            perror("init_sem");
            exit(1);
        }
    }
    int cnt = 0;
    while(1) {
        printf("now sem value : %d\n", sem_Look(sem_id));
        sem_P(sem_id);
        cnt++;
        printf("cnt = %d\n", cnt);
    }

    return 0;
}